package com.pearadmin.pro.modules.weixin.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.pearadmin.pro.common.secure.uutoken.SecureUserToken;
import com.pearadmin.pro.common.secure.uutoken.SecureUserTokenService;
import com.pearadmin.pro.common.tools.core.OkHttpUtils;
import com.pearadmin.pro.common.web.domain.Result;
import com.pearadmin.pro.common.web.domain.ResultCode;
import com.pearadmin.pro.modules.sys.domain.SysUser;
import com.pearadmin.pro.modules.sys.service.SysUserService;
import com.pearadmin.pro.modules.weixin.dto.apply.ApplyeventDTO;
import com.pearadmin.pro.modules.weixin.service.EnterpriseWinXinService;
import com.pearadmin.pro.modules.weixin.util.AesException;
import com.pearadmin.pro.modules.weixin.util.WXBizMsgCrypt;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;

;

/**
 * taService业务层处理
 *
 * @author ChenJian
 * @date 2021-08-22
 */
@Service
@Slf4j
public class EnterpriseWinXinServiceImpl implements EnterpriseWinXinService
{
    @Resource
    private RedisTemplate<String, String> redisTemplate;
    //企业微信id
    @Value("${weixin.corpId}")
    private String corpId ;
    //应用id
    @Value("${weixin.corpSecret}")
    private String corpSecret;
    //获取url
    @Value("${weixin.qyApiUrl}")
    private String qyApiUrl;

    @Value("${weixin.authorizeUrl}")
    private String authorizeUrl;

    @Value("${weixin.sToken}")
    private String sToken ;

    @Value("${weixin.sEncodingAESKey}")
    private String sEncodingAESKey;


    @Resource
    private SysUserService sysUserService;

    @Resource
    private SecureUserTokenService customUserDetailsTokenService;

    /**
     * @return
     */
    @Override
    public String getToken() {
        String key = "?corpid="+corpId+"&corpsecret="+corpSecret;
        if(!ObjectUtils.isEmpty(redisTemplate.opsForValue().get(key))){
            //缓存中存在 缓存中取
            return redisTemplate.opsForValue().get(key).toString();
        }
        //缓存中不存在 请求微信获取
        String url = qyApiUrl+"cgi-bin/gettoken"+key;
        String result = OkHttpUtils.httpGet(url);
        log.info("获取企业微信getToken:{}",result);
        JSONObject reJson = JSONObject.parseObject(result);
        if("0".equals(reJson.getString("errcode"))){
            //表示获取成功
            String access_token = reJson.getString("access_token");
            Integer expires_in = reJson.getInteger("expires_in");
            redisTemplate.opsForValue().set(key,access_token, expires_in,TimeUnit.SECONDS);
            return access_token;
        }
        return null;
    }

    /**
     * 构造网页授权链接
     * @param redirect_uri 授权后重定向的回调链接地址
     * @param state 重定向后会带上state参数，企业可以填写a-zA-Z0-9的参数值，
     * @return
     */
    @Override
    public String getAuthorizeUrl(String redirect_uri, String state) {
        String url = authorizeUrl+"?appid="+corpId+"&redirect_uri="+redirect_uri+"&response_type=code&scope=snsapi_base&state="+state+"#wechat_redirect";
        return url;
    }

    /**
     * 获取访问用户身份
     * @param code 前端返回
     * @return
     */
    @Override
    public JSONObject getUserInfo(String code) {
        StringBuffer url = new StringBuffer(qyApiUrl);
        url.append("cgi-bin/user/getuserinfo");
        url.append("?access_token=");
        url.append(getToken());
        url.append("&code=");
        url.append(code);
        //缓存中不存在 请求微信获取
        String result = OkHttpUtils.httpGet(url.toString());
        log.info("获取访问用户身份:{}",result);
        return JSONObject.parseObject(result);
    }

    @Override
    public JSONObject getInfo(String userid) {
        StringBuffer url = new StringBuffer(qyApiUrl);
        url.append("cgi-bin/user/get");
        url.append("?access_token=");
        url.append(getToken());
        url.append("&userid=");
        url.append(userid);
        //缓存中不存在 请求微信获取
        String result = OkHttpUtils.httpGet(url.toString());
        log.info("读取成员信息:{}",result);
        return JSONObject.parseObject(result);
    }


    @Override
    public Result Login(String userid) {
        SysUser user = sysUserService.getOneWeiXinUserId(userid);
        if(!ObjectUtils.isEmpty(user)){
            //返回登录成功信息
            return LoginSuccess(user);
        }
        //获取到微信用户信息
        JSONObject weiXinUser = getInfo(userid);
        String weiXinUserId = weiXinUser.getString("userid");
        String mobile = weiXinUser.getString("mobile");
        String open_userId = weiXinUser.getString("open_userid");
        user = sysUserService.getOnePhone(mobile);
        if(!ObjectUtils.isEmpty(user)){
            //登录失败返回数据
            return Result.success(ResultCode.USER_USERNAME_NOT_FOUND,null,null,user.getUsername());
        }
        //绑定企业微信 用户
        user.setWeiXinUserId(weiXinUserId);
        user.setWeiXinOpenId(open_userId);
        sysUserService.updateById(user);
        //返回登录成功信息
        return LoginSuccess(user);
    }



    /**
     * 登录成功封装数据
     * @param user
     * @return
     */
    private Result LoginSuccess(SysUser user){
        SecureUserToken userToken = customUserDetailsTokenService.createToken(user);
        String tokenKey = customUserDetailsTokenService.saveToken(userToken);
        String tokenValue = userToken.getToken();
        return Result.success(ResultCode.LOGIN_SUCCESS,tokenKey,tokenValue,user.getUsername());
    }


    /**
     * 提交审批 企业微信
     * @param applyeventDTO
     * @return  返回企业微信审批流 表单编号
     */
    @Override
    public String applyevent(ApplyeventDTO applyeventDTO) {
        StringBuffer url = new StringBuffer(qyApiUrl);
        url.append("cgi-bin/oa/applyevent");
        url.append("?access_token=");
        url.append(getToken());
        //缓存中不存在 请求微信获取
        String result = OkHttpUtils.httpPostJson(url.toString(),JSONObject.toJSONString(applyeventDTO));
        log.info("提交审批:{}",result);
        JSONObject reJson = JSONObject.parseObject(result);
        String sp_no = null;
        if("0".equals(reJson.getString("errcode"))){
            //表示获取成功
             sp_no = reJson.getString("sp_no");
        }
        return sp_no;
    }

    @Override
    public void Callback(HttpServletRequest request, HttpServletResponse response) {
        //当你提交以上信息时，企业号将发送GET请求到填写的URL上，GET请求携带四个参数，企业在获取时需要做urldecode处理，否则会验证不成功
        // 解析出url上的参数值如下：
        String sVerifyMsgSig = request.getParameter("msg_signature");
        // 时间戳
        String sVerifyTimeStamp = request.getParameter("timestamp");
        // 随机数
        String sVerifyNonce = request.getParameter("nonce");
        // 随机字符串
        String sVerifyEchoStr = request.getParameter("echostr");
        try {
            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, corpId);
            String sEchoStr = wxcpt.VerifyURL(sVerifyMsgSig, sVerifyTimeStamp,
                    sVerifyNonce, sVerifyEchoStr);
            log.info("接收企业微信回调信息: {}" ,sEchoStr);
            // 验证URL成功，将sEchoStr返回
            OkHttpUtils.write(response,sEchoStr);
        } catch (Exception e) {
            //验证URL失败，错误原因请查看异常
            e.printStackTrace();
        }
    }




}
